package com.zhifei.system.service.impl;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zhifei.common.utils.Constant;
import com.zhifei.common.utils.DateUtils;
import com.zhifei.common.utils.Result;
import com.zhifei.common.utils.StringUtils;
import com.zhifei.common.utils.excel.ExcelUtils;
import com.zhifei.system.domain.DevProjectEntity;
import com.zhifei.system.domain.DevProjectManhoursEntity;
import com.zhifei.system.domain.DingUserEntity;
import com.zhifei.system.domain.dto.DevProjectManhoursExcelDTO;
import com.zhifei.system.domain.vo.DevProjectManhoursVo;
import com.zhifei.system.mapper.DevProjectManhoursMapper;
import com.zhifei.system.service.DevProjectManhoursService;
import com.zhifei.system.service.DevProjectService;
import com.zhifei.system.service.DingUserService;
import com.zhifei.system.util.PageUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;

@Service
public class DevProjectManhoursServiceImpl extends ServiceImpl<DevProjectManhoursMapper, DevProjectManhoursEntity> implements DevProjectManhoursService {

    @Autowired
    private DingUserService dingUserService;
    @Autowired
    private DevProjectService devProjectService;
    @Autowired
    private DevProjectManhoursMapper devProjectManhoursMapper;

    @Override
    public Result importMonth(MultipartFile multipartFile,String month) {
        List<DevProjectManhoursEntity> devProjectManhoursEntityList = new ArrayList<>();
        List<Object> devProjectManhoursExcelList = ExcelUtils.importExcel(multipartFile, new DevProjectManhoursExcelDTO());
        if (Objects.isNull(devProjectManhoursExcelList)) {
            return Result.error("文件格式不支持，请采用样式模板");
        }
        Date yearmoDate = DateUtils.parseDate(month);
//        Integer count = this.lambdaQuery().eq(DevProjectManhoursEntity::getMonth, yearmoDate).count();
//        if(count>0){
//            return Result.error("该月份数据已导入，请勿重复导入");
//        }
        List<DingUserEntity> dingUserEntityList = dingUserService.lambdaQuery().list();
        for (int i = 0; i < devProjectManhoursExcelList.size(); i++) {
            DevProjectManhoursExcelDTO devProjectManhoursExcelDTO = (DevProjectManhoursExcelDTO) devProjectManhoursExcelList.get(i);
            if (StringUtils.isEmpty(devProjectManhoursExcelDTO.getMonth())) {
                return Result.error("第" + (i + 1) + "行数据中：" + "日期不能为空！");
            }
            if (StringUtils.isEmpty(devProjectManhoursExcelDTO.getProjectCode())) {
                return Result.error("第" + (i + 1) + "行数据中：" + "项目编码不能为空！");
            }
            if (StringUtils.isEmpty(devProjectManhoursExcelDTO.getJobNum())) {
                return Result.error("第" + (i + 1) + "行数据中：" + "工号不能为空！");
            }
            if (StringUtils.isEmpty(devProjectManhoursExcelDTO.getManhours())) {
                return Result.error("第" + (i + 1) + "行数据中：" + "登记工时不能为空！");
            }
            DevProjectManhoursEntity devProjectManhoursEntity = new DevProjectManhoursEntity();
            devProjectManhoursEntity.setMonth(yearmoDate);
            devProjectManhoursEntity.setProjectCode(devProjectManhoursExcelDTO.getProjectCode());
            String jobNum = devProjectManhoursExcelDTO.getJobNum();
            devProjectManhoursEntity.setJobNum(jobNum);
            BigDecimal manhours = new BigDecimal(devProjectManhoursExcelDTO.getManhours());
            devProjectManhoursEntity.setManhours(manhours);
            for(DingUserEntity dingUserEntity : dingUserEntityList){
                if(StringUtils.isNotEmpty(dingUserEntity.getJobNumber()) && jobNum.equals(dingUserEntity.getJobNumber())){
                    devProjectManhoursEntity.setMonthPay(dingUserEntity.getMonthPay());
                    if(dingUserEntity.getMonthPay()!=null){
                        //人工成本=月薪/21.75/8*登记工时
                        devProjectManhoursEntity.setLaborCost(dingUserEntity.getMonthPay()
                                .divide(new BigDecimal(174),2, RoundingMode.HALF_UP)
                                .multiply(manhours));
                    }
                }
            }
            devProjectManhoursEntityList.add(devProjectManhoursEntity);
        }
        this.saveBatch(devProjectManhoursEntityList);
        CompletableFuture.runAsync(() -> this.calcProjectLaborCost(devProjectManhoursEntityList));
        return Result.success("导入成功");
    }

    @Override
    public PageUtils pageManhours(Map<String, Object> params) {
        Page page = new Page(Long.parseLong((String)params.get(Constant.PAGE)),Long.parseLong((String)params.get(Constant.LIMIT)));
        String projectCode = (String) params.get("projectCode");
        String jobNum = (String) params.get("jobNum");
        String monthStartDate = (String) params.get("monthStartDate");
        String monthEndDate = (String) params.get("monthEndDate");
        List<DevProjectManhoursVo> devProjectManhoursVoList = devProjectManhoursMapper.pageManhours(page,projectCode,jobNum,monthStartDate,monthEndDate);
        page.setRecords(devProjectManhoursVoList);
        return new PageUtils(page);
    }

    public void calcProjectLaborCost(List<DevProjectManhoursEntity> devProjectManhoursEntityList){
        List<String> projectCodeList = devProjectManhoursEntityList.stream().map(DevProjectManhoursEntity::getProjectCode).collect(Collectors.toList());
        List<DevProjectEntity> devProjectEntityList = devProjectService.lambdaQuery().in(DevProjectEntity::getProjectCode,projectCodeList).list();
        Map<String, DoubleSummaryStatistics> collectGroupByManhours = devProjectManhoursEntityList.stream().collect(
                Collectors.groupingBy(DevProjectManhoursEntity::getProjectCode,
                Collectors.summarizingDouble(t -> t.getManhours().doubleValue())));
        Map<String, DoubleSummaryStatistics> collectGroupByLaborCost = devProjectManhoursEntityList.stream().collect(
                Collectors.groupingBy(DevProjectManhoursEntity::getProjectCode,
                        Collectors.summarizingDouble(t -> t.getLaborCost().doubleValue())));
        for(DevProjectEntity devProjectEntity : devProjectEntityList){
            for (String projectCode : collectGroupByManhours.keySet()) {
                if(projectCode.equals(devProjectEntity.getProjectCode())){
                    Double manhours = collectGroupByManhours.get(projectCode).getSum();
                    devProjectEntity.setProjectWork(BigDecimal.valueOf(manhours));
                }
            }
            for (String projectCode : collectGroupByLaborCost.keySet()) {
                if(projectCode.equals(devProjectEntity.getProjectCode())){
                    Double laborCost = collectGroupByLaborCost.get(projectCode).getSum();
                    devProjectEntity.setLaborCost(BigDecimal.valueOf(laborCost));
                }
            }
        }
        devProjectService.updateBatchById(devProjectEntityList);
    }

}
